

/**
 * 对象池配置
 */
export interface PoolConfig<T> {
    /** 对象池容量 */
    maxSize?: number;
    /** 初始预创建数量，默认0 */
    preloadSize?: number;
    /** 创建对象 */
    onCreate(): T;
    /** 对象被从池中取出时调用 */
    onUse?(t: T): void;
    /** 对象被回收到池中时调用 */
    onRecycle?(t: T): void;
    /** 对象被清理时调用 */
    onDestroy?(t: T): void;
}

export class ObjectPool<T> {
    private _objects: T[] = [];
    private _allObjects: Set<T> = new Set(); // 新增：存储所有创建的对象
    private _maxSize: number;
    private _config: PoolConfig<T>;

    /**
     * 获取池的当前大小
     */
    get size(): number {
        return this._objects.length;
    }

    /** 
     * 获取池的最大容量
     */
    get maxSize(): number {
        return this._maxSize;
    }

    /**
     * 获取所有创建的对象（包括正在使用的）
     */
    get allObjects(): ReadonlySet<T> {
        return this._allObjects;
    }

    /**
     * 获取正在使用中的对象数量
     */
    get activeCount(): number {
        return this._allObjects.size - this._objects.length;
    }

    /**
     * 配置里面的onUse和onRecycle方法会在对象被使用和回收时调用
     * @param config 
     */
    constructor(config: PoolConfig<T>) {
        this._config = config;
        this._maxSize = config?.maxSize || 50;

        const preloadSize = Math.min(config?.preloadSize || 0, this._maxSize);
        for (let i = 0; i < preloadSize; i++) {
            const obj = this._config.onCreate();
            this._objects.push(obj);
            this._allObjects.add(obj); // 添加到所有对象列表
        }
    }

    /**
     * 从池中获取对象
     */
    get(): T {
        let obj: T;

        if (this._objects.length > 0) {
            obj = this._objects.pop()!;
        } else {
            obj = this._config.onCreate();
            this._allObjects.add(obj); // 添加新创建的对象到列表
        }

        this._config.onUse?.(obj);
        return obj;
    }

    /**
     * 将对象放回池中
     */
    put(obj: T): boolean {
        if (!obj) return false;

        // 检查对象是否属于这个池
        if (!this._allObjects.has(obj)) {
            console.warn('尝试回收不属于此池的对象');
            return false;
        }

        // 检查对象是否已经在池中
        if (this._objects.indexOf(obj) >= 0) {
            console.warn('对象已经在池中，重复回收');
            return false;
        }

        if (this._objects.length >= this._maxSize) {
            // 池已满，销毁对象
            this._config.onDestroy?.(obj);
            this._allObjects.delete(obj); // 从所有对象列表中移除
            return false;
        }

        this._config.onRecycle?.(obj);
        this._objects.push(obj);
        return true;
    }

    /**
     * 检查对象是否属于此池
     */
    contains(obj: T): boolean {
        return this._allObjects.has(obj);
    }

    /**
     * 检查对象是否正在使用中
     */
    isActive(obj: T): boolean {
        return this._objects.indexOf(obj) >= 0;
    }

    /**
     * 强制回收所有正在使用的对象
     */
    forceRecycleAll(): void {
        // 获取所有正在使用的对象
        const activeObjects = Array.from(this._allObjects).filter(obj => this.isActive(obj));

        activeObjects.forEach(obj => {
            if (this._objects.length < this._maxSize) {
                this._config.onRecycle?.(obj);
                this._objects.push(obj);
            } else {
                this._config.onDestroy?.(obj);
                this._allObjects.delete(obj);
            }
        });
    }

    /**
     * 清理池中的所有对象----！！！包括正在使用的
     */
    clear() {
        this.forceRecycleAll();
        const actualCount = this._objects.length;
        for (let i = 0; i < actualCount; i++) {
            const obj = this._objects.pop();
            if (obj) {
                this._config.onDestroy?.(obj);
                this._allObjects.delete(obj); // 从所有对象列表中移除
            }
        }
        this._objects.length = 0;
        this._allObjects.clear();
    }
}